﻿using UnityEngine;

public class CreatorElement {
	// === Public =====================================================================================================
	public static CreatorElement CreateInstance() {
		var instance = new CreatorElement();
		return instance;
	}

	public ElementCtrl Create(PropertyElement properties) {
		var gameObject = GetGameObject(properties.Type);
		SetName(gameObject, properties.Name);
		SetTransform(gameObject, properties);
		SetTexture(gameObject, properties);
		SetComponents(gameObject, properties);
		var elementModel = GetElementModel(properties);
		return GetElementCtrl(elementModel, gameObject);
	}

	// === Private ====================================================================================================
	// --- GameObject ---
	private GameObject GetGameObject(ElementType elementType) {
		switch (elementType) {
			case ElementType.Tile:
				return Tools.GameObject.Create(ResourceConstants.Prefabs.TILE);
			case ElementType.Wall:
				return Tools.GameObject.Create(ResourceConstants.Prefabs.TILE);
			default:
				return Tools.GameObject.Create(ResourceConstants.Prefabs.TILE);
		}
	}

	// --- Property ---
	private void SetName(Object go, string name = null) {
		if (name == null) { return; }
		go.name = name;
	}

	private void SetTransform(GameObject go, ITransform transform) {
		go.transform.position = transform.Position;
		go.transform.rotation = transform.Rotation;
		go.transform.localScale = transform.Scale;
	}

	private void SetTexture(GameObject go, IMaterial properties) {
		if (properties.TexturePath != null) {
			go.renderer.material.shader = Shader.Find("Transparent/Diffuse");
			go.renderer.material.mainTexture = Tools.Resources.GetObjectFromResources<Texture>(properties.TexturePath);
		}
		go.renderer.material.mainTextureScale = properties.TextureScale;
		go.renderer.material.color = properties.Color;
	}

	private void SetComponents(GameObject go, IComponent components) {
		foreach (var component in components.Components) {
			AddComponent(go, component);
		}
	}

	private void AddComponent(GameObject go, string className) {
		go.AddComponent(className);
	}

	private Element GetElementModel(PropertyElement properties) {
		return new Element {
			ElementType = properties.Type,
			Position = properties.Position,
			TexturePath = properties.TexturePath
		};
	}

	private ElementCtrl GetElementCtrl(Element model, GameObject view) {
		return new ElementCtrl(model, view);
	}
}
